package com.faya.green.utils;

import com.faya.green.model.Authority;
import com.faya.green.model.AuthorityRole;
import com.faya.green.model.SysLog;

import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户：LX
 * 创建时间： 2017/10/9. 9:49
 * 地点：广州
 * 目的: 根据model 自动生成 mapper service dao 层的工具
 * 结果：
 * 颜色设置：
 * 40: 黑 30: 黑
 * 41: 红 31: 红
 * 42: 绿 32: 绿
 * 43: 黄 33: 黄
 * 44: 蓝 34: 蓝
 * 45: 紫 35: 紫
 * 46: 深绿 36: 深绿
 * 47: 白色 37: 白色
 *
 * \033[0m 关闭所有属性
 * \033[1m 设置高亮度
 * \03[4m 下划线
 * \033[5m 闪烁
 * \033[7m 反显
 * \033[8m 消隐
 */
public class CRUPUtils {

    /**
     * 使用说明：
     *  本工具类的作用： 根据model自动生成dao  service  mapper，另外将基础的 增加、修改、根据主键查询自动生成这个sql和接口方法
     *  本工具类有几个约定，model的第一个属性是默认的id，如果不是请自行调整
     *  本工具类的默认使用utf-8的编码，如果需要其他编码，请自行指定
     *  生成代码的时候可能会有一些数据类型不识别，需要自行查看报错信息并解决。
     *
     *  如果已经存在要生成的文件，则会跳过不进行处理
     *  默认生成的代码文件格式和命名规范是这样的：
     *      service
     *          类名Service
     *              impl
     *                  类名ServiceImpl
     *      dao
     *          类名Dao
     *
     *  使用：直接修改 servicePath 和 daoPath 以及 xmlMapping 变量名即可
     *      指定好要生成的位置之后，文件会放在这个目录之下，如果不希望生成文件，只需要生成sql的话，直接调用 findIdMapper()
     *      insertMapper()  updateMapper()  方法即可，对于有30个以上字段的model，可以快速方便的将update insert语句生成
     */

    /**
     * 指定编码
     */
    private String encode = "UTF-8";
    /**
     * 指定service层路径
     */
    private String servicePath = "E:\\kaiFa\\IDEATest\\greenSource\\src\\main\\java\\com\\faya\\green\\service";
    /**
     * 指定dao层路径
     */
    private String daoPath = "E:\\kaiFa\\IDEATest\\greenSource\\src\\main\\java\\com\\faya\\green\\dao\\authority";
    /**
     * mapping文件的位置,在他的下面创建文件。 会生成 类名Mapper.xml 的xml文件
     */
    private String xmlMapping = "E:\\kaiFa\\IDEATest\\greenSource\\src\\main\\resources\\mapper\\sqlite";


    public static void main(String[] args) {
        CRUPUtils crupUtils = new CRUPUtils();
        SysLog card = new SysLog();

//        生成语句
        crupUtils.findIdMapper(card);
        crupUtils.insertMapper(card);
        crupUtils.updateMapper(card);


        //生成xml文件 和serivce文件
//        crupUtils.serviceGenerate(card);
//        crupUtils.xmlMapping(card);
    }

    /**
     * 自动生成service
     * @param obj
     */
    private void serviceGenerate(Object obj){
        StringBuffer sb = new StringBuffer();
        String namePackage = obj.getClass().getName(); //获取类名
        String name = namePackage.substring(namePackage.lastIndexOf(".") + 1, namePackage.length()); //对类名进行剪切

        String className = name + "Service";
        //包的路径
        String packageStr = servicePath.substring(servicePath.indexOf("src\\") + 4, servicePath.length());
        packageStr = packageStr.replace('\\', '.');

        sb.append("package ");
        sb.append(packageStr);
        sb.append(";");
        sb.append("\r\n"); //换行
        sb.append("\r\n"); //换行
        sb.append("import " + namePackage + ";");
        sb.append("\r\n"); //换行
        sb.append("\r\n"); //换行
        sb.append("public interface ");
        sb.append(className + " {");
        sb.append("\r\n"); //换行
        sb.append("\r\n"); //换行


        //生成根据主键查询的sql
        Map xmlMap = findIdMapper(obj);
        if (xmlMap != null){
            sb.append("\t" + name + " " + xmlMap.get("id") + "(String id);");
            sb.append("\r\n"); //换行
            sb.append("\r\n"); //换行
        }


        //生成更新的sql
        Map updateMap = updateMapper(obj);
        if (updateMap != null){
            sb.append("\t" + "void " + updateMap.get("id") + "(" + name + " " + name.toLowerCase() + ");");
            sb.append("\r\n"); //换行
            sb.append("\r\n"); //换行
        }

        //生成新增的sql
        Map addMap = insertMapper(obj);
        if (addMap != null){
            sb.append("\t" + name + " " + addMap.get("id") + "(" + name + " " + name.toLowerCase() + ");");
            sb.append("\r\n"); //换行
            sb.append("\r\n"); //换行
        }

        sb.append("}");


        System.out.println("\033[37;1m" + "" + "\033[0m"); //对颜色进行初始化操作
        System.out.println(sb.toString());

        //对路径进行初始化
        init(servicePath);

        File fileJava = new File(servicePath + "\\" +className +".java");
        createFileWrite(sb.toString(), fileJava);


        /**
         * 生成service的实现层
         */
        StringBuffer sbu = new StringBuffer();
        sbu.append("package ");
        sbu.append(packageStr + ".impl");
        sbu.append(";");
        sbu.append("\r\n"); //换行
        sbu.append("\r\n"); //换行
        sbu.append("import " + namePackage + ";");
        sbu.append("\r\n"); //换行
        sbu.append("import " + packageStr + "." + className + ";");
        sbu.append("\r\n"); //换行
        sbu.append("\r\n"); //换行
        sbu.append("import org.springframework.beans.factory.annotation.Autowired;");
        sbu.append("\r\n"); //换行
        sbu.append("import org.springframework.stereotype.Service;");
        sbu.append("\r\n"); //换行
        sbu.append("\r\n"); //换行
        sbu.append("@Service"); //换行
        sbu.append("\r\n"); //换行
        sbu.append("public class " + className + "Impl" + " implements " + className + " {");
        sbu.append("\r\n"); //换行
        sbu.append("\r\n"); //换行
        sbu.append("\t//压制全部警告");
        sbu.append("\r\n"); //换行
        sbu.append("\t@SuppressWarnings(\"all\")");
        sbu.append("\r\n"); //换行
        sbu.append("\t@Autowired");
        sbu.append("\r\n"); //换行
        sbu.append("\tprivate " + name + "Dao " + name.toLowerCase() + "Dao;");
        sbu.append("\r\n"); //换行
        sbu.append("\r\n"); //换行


        //根据id查询的语句
        if (xmlMap != null){
            sbu.append("\t@Override");
            sbu.append("\r\n"); //换行
            sbu.append("\tpublic " + name + " " + xmlMap.get("id") + "(String id){");
            sbu.append("\r\n"); //换行
            sbu.append("\t\t" + name.toLowerCase() + "Dao." + xmlMap.get("id") + "(id);");
            sbu.append("\r\n"); //换行
            sbu.append("\t}");
            sbu.append("\r\n"); //换行
            sbu.append("\r\n"); //换行
        }

        //生成更新的sql
        if (updateMap != null){
            sbu.append("\t@Override");
            sbu.append("\r\n"); //换行
            sbu.append("\tpublic " + "void " + updateMap.get("id") + "(" + name + " " + name.toLowerCase() + "){");
            sbu.append("\r\n"); //换行
            sbu.append("\t\t" + name.toLowerCase() + "Dao." + updateMap.get("id") + "(" + name.toLowerCase() + ");");
            sbu.append("\r\n"); //换行
            sbu.append("\t}");
            sbu.append("\r\n"); //换行
            sbu.append("\r\n"); //换行
        }

        //生成新增的sql
        if (addMap != null){
            sbu.append("\t@Override");
            sbu.append("\r\n"); //换行
            sbu.append("\tpublic " + "void " + addMap.get("id") + "(" + name + " " + name.toLowerCase() + "){");
            sbu.append("\r\n"); //换行
            sbu.append("\t\t" + name.toLowerCase() + "Dao." + addMap.get("id") + "(" + name.toLowerCase() + ");");
            sbu.append("\r\n"); //换行
            sbu.append("\t}");
            sbu.append("\r\n"); //换行
            sbu.append("\r\n"); //换行
        }


        init(servicePath + "\\impl");

        File fileJavaImpl = new File(servicePath + "\\impl\\" + className +"Impl.java");
        createFileWrite(sbu.toString(), fileJavaImpl);

    }

    /**
     * 自动生成dao 层
     * @param obj
     * 返回dao层的接口
     */
    private String daoGenerate(Object obj){
        StringBuffer sb = new StringBuffer();
        String namePackage = obj.getClass().getName(); //获取类名
        String name = namePackage.substring(namePackage.lastIndexOf(".") + 1, namePackage.length()); //对类名进行剪切

        String className = name + "Dao";
        //包的路径
        String packageStr = daoPath.substring(daoPath.indexOf("src\\") + 4, daoPath.length());
        packageStr = packageStr.replace('\\', '.');

        sb.append("package ");
        sb.append(packageStr);
        sb.append(";");
        sb.append("\r\n"); //换行
        sb.append("\r\n"); //换行
        sb.append("import " + namePackage + ";");
        sb.append("\r\n"); //换行
        sb.append("\r\n"); //换行
        sb.append("public interface ");
        sb.append(className + " {");
        sb.append("\r\n"); //换行
        sb.append("\r\n"); //换行


        //生成根据主键查询的sql
        Map xmlMap = findIdMapper(obj);
        if (xmlMap != null){
            sb.append("\t" + name + " " + xmlMap.get("id") + "(String id);");
            sb.append("\r\n"); //换行
            sb.append("\r\n"); //换行
        }


        //生成更新的sql
        Map updateMap = updateMapper(obj);
        if (updateMap != null){
            sb.append("\t" + "void " + updateMap.get("id") + "(" + name + " " + name.toLowerCase() + ");");
            sb.append("\r\n"); //换行
            sb.append("\r\n"); //换行
        }

        //生成新增的sql
        Map addMap = insertMapper(obj);
        if (addMap != null){
            sb.append("\t" + name + " " + addMap.get("id") + "(" + name + " " + name.toLowerCase() + ");");
            sb.append("\r\n"); //换行
            sb.append("\r\n"); //换行
        }

        sb.append("}");


        System.out.println("\033[37;1m" + "" + "\033[0m"); //对颜色进行初始化操作
        System.out.println(sb.toString());

        //对路径进行初始化
        init(daoPath);

        File fileJava = new File(daoPath + "\\" +className +".java");
        createFileWrite(sb.toString(), fileJava);
        return packageStr + "." + className;
    }

    /**
     * 自动生成mapper文件到指定位置，并生成相应的常用代码
     * @param obj model对象
     */
    private void xmlMapping(Object obj){
        //生成dao
        String dao = daoGenerate(obj);


        String namePackage = obj.getClass().getName(); //获取类名
        String name = namePackage.substring(namePackage.lastIndexOf(".") + 1, namePackage.length()); //对类名进行剪切
        //拼成mapper
        String mapperName = (name.toLowerCase()) + "Mapper.xml";
        String mapperPath = xmlMapping + "\\" + mapperName;


        StringBuffer sb = new StringBuffer();
        sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
        sb.append("\r\n"); //换行
        sb.append("<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">");
        sb.append("\r\n"); //换行
        sb.append("\r\n"); //换行
        sb.append("<mapper namespace=\"" + dao + "\">");
        sb.append("\r\n"); //换行
        sb.append("\r\n"); //换行

        //生成根据主键查询的sql
        Map findMap = findIdMapper(obj);
        if (findMap != null){
            sb.append(findMap.get("sql"));
            sb.append("\r\n"); //换行
            sb.append("\r\n"); //换行
        }


        //生成更新的sql
        Map updateMap = updateMapper(obj);
        if (updateMap != null){
            sb.append(updateMap.get("sql"));
            sb.append("\r\n"); //换行
            sb.append("\r\n"); //换行
        }

        //生成新增的sql
        Map addMap = insertMapper(obj);
        if (addMap != null){
            sb.append(addMap.get("sql"));
            sb.append("\r\n"); //换行
            sb.append("\r\n"); //换行
        }

        sb.append("\r\n"); //换行
        sb.append("\r\n"); //换行
        sb.append("</mapper>");

        System.out.println("\033[37;1m" + "" + "\033[0m"); //对颜色进行初始化操作
        System.out.println(sb.toString());

        //对路径进行初始化
        init(xmlMapping);

        File fileXML = new File(mapperPath);
        createFileWrite(sb.toString(), fileXML);
    }


    /**
     * 生成根据主键查询的sql，不能正常转换的不会自动处理，只会提醒
     * @param obj model对象
     */
    private Map findIdMapper(Object obj){
        if (obj != null){
            StringBuffer sb = new StringBuffer();
            String namePackage = obj.getClass().getName(); //获取类名
            String name = namePackage.substring(namePackage.lastIndexOf(".") + 1, namePackage.length()); //对类名进行剪切
            System.out.println(name + "==========生成根据主键查询的sql start==============================================================================" );
            //获取全部是属性名
            String[] strArr = getFiledName(obj);
            String attributeName = strArr[0]; //获得属性名,默认第一个是主键
            String transformation = transformation(attributeName, obj);
            //出错的
            String st = "";
            String sqlId = ""; //生成的sql的id
            if (!"jdbcType=暂无对应数据".equals(transformation)){
                Map map = new HashMap<>();
                map.put("name", attributeName); //属性名
                map.put("type", transformation); //字段类型

                sqlId = "get" + name + "ById";
                sb.append("<select id=\"" + sqlId + "\" parameterType=\"java.lang.String\" resultType=\"" + namePackage + "\">");
                sb.append("\r\n"); //换行

                sb.append("\tselect * from ");
                sb.append(name);
                sb.append(" where " + attributeName + " = #{" + map.get("name") + ", " + map.get("type") + "}");

                sb.append("\r\n"); //换行
                sb.append("</select>");

            }  else {
                //错误的进行记录，防止错误的漏了
                st = attributeName;
            }

            System.out.println("\033[33;1m" + sb.toString() + "\033[0m");
            System.out.println(name +"==========生成根据主键查询的sql end==============================================================================");
            System.out.println("无法转换的属性：" + "\033[31;1m" + st + "\033[0m");

            Map m = new HashMap();
            m.put("id", sqlId); //xml上的id
            m.put("sql", sb.toString()); //生成的sql加拼好的外壳

            return m;
        } else {
            return null;
        }
    }

    /**
     * 生成更新的语句 不能正常转换的不会自动处理，只会提醒
     * @param obj
     */
    private Map updateMapper(Object obj){
        if (obj != null) {
            System.out.println("\033[37;1m" + "" + "\033[0m"); //对颜色进行初始化操作
            System.out.println("==========生成update 语句 start==============================================================================");
            String namePack = obj.getClass().getName(); //获取类名
            String name = namePack.substring(namePack.lastIndexOf(".") + 1, namePack.length()); //对类名进行剪切

            StringBuffer sb = new StringBuffer();
            String sqlId = ""; //生成的sql的id
            sqlId = "update" + name;
            sb.append("<update id=\"" + sqlId + "\" parameterType=\"" + namePack + "\">");
            sb.append("\r\n"); //换行
            sb.append("\tupdate ");
            sb.append(name);
            sb.append("\r\n"); //换行
            sb.append("\t<set>" + "\r\n");

            //获取全部是属性名
            String[] strArr = getFiledName(obj);
            List<Map> list = new ArrayList<Map>(); //用于保存返回的jdbc类型
            StringBuffer st = new StringBuffer();
            if (strArr != null && strArr.length > 0){
                for (int i = 0; i < strArr.length; i ++ ){
                    String attributeName = strArr[i]; //获得属性名
                    String transformation = transformation(attributeName, obj);
                    if (!"jdbcType=暂无对应数据".equals(transformation)){
                        Map map = new HashMap<>();
                        map.put("name", attributeName); //属性名
                        map.put("type", transformation); //字段类型
                        list.add(map);
                    }  else {
                        //错误的进行记录，防止错误的漏了
                        st.append(attributeName);
                    }
                }

                //获取到全部属性名与字段类型后的处理
                String id = "";
                if (list != null && list.size() > 0){
                    for (int i = 0; i < list.size(); i ++){
                        //默认第一条为主键
                        if (i == 0){
                            if ("error=1".equals(list.get(i).get("type"))){
                                id = "where " + list.get(i).get("name") + " = #{" + list.get(i).get("name") + "}";
                            } else {
                                id = "where " + list.get(i).get("name") + " = #{" + list.get(i).get("name") + "," + list.get(i).get("type") + "}";
                            }
                        }  else {
                            if ("error=1".equals(list.get(i).get("type"))){
                                sb.append("\t\t" + "<if test=\"" + list.get(i).get("name") + " != null and " + list.get(i).get("name") + " != ''\"" + ">");
//                                sb.append("\r\n"); 暂时去掉，
                                sb.append("\t\t\t" + list.get(i).get("name") + " = #{" + list.get(i).get("name") + "},");
//                                sb.append("\r\n"); 暂时去掉，
                                sb.append("\t\t" + "</if>");
                                sb.append("\t\r\n");
                            } else {
                                sb.append("\t\t" + "<if test=\"" + list.get(i).get("name") + " != null and " + list.get(i).get("name") + " != ''\"" + ">");
//                                sb.append("\r\n");
                                sb.append("\t\t\t" + list.get(i).get("name") + " = #{" + list.get(i).get("name") + "," + list.get(i).get("type") + "},");
//                                sb.append("\r\n");
                                sb.append("\t\t" + "</if>");
                                sb.append("\r\n");
                            }
                        }
                    }
                    sb.append("\t</set>");
                    sb.append("\r\n");
                    sb.append("\t" + id);
                    sb.append("\r\n");
                    sb.append("</update>");
                    System.out.println("\033[33;1m" + sb.toString() + "\033[0m");
                    System.out.println("==========生成update 语句 end==============================================================================");
                    System.out.println("无法转换的属性：" + "\033[31;1m" + st + "\033[0m");

                    Map m = new HashMap();
                    m.put("id", sqlId); //xml上的id
                    m.put("sql", sb.toString()); //生成的sql加拼好的外壳

                    return m;
                }
            }
        }
        return null;
    }

    /**
     * 生成insert 语句，不能正常转换的不会自动处理，只会提醒
     * @param obj
     */
    private Map insertMapper(Object obj){
        if (obj != null){
            //初始化颜色
            System.out.println("\033[37;1m" + "" + "\033[0m");
            System.out.println("==========生成insert 语句 start==============================================================================");

            String namePack = obj.getClass().getName(); //获取类名
            String name = namePack.substring(namePack.lastIndexOf(".") + 1, namePack.length()); //对类名进行剪切

            StringBuffer sb = new StringBuffer();
            String sqlId = ""; //生成的sql的id
            sqlId = "add" + name;
            sb.append("<insert id=\"" + sqlId + "\" parameterType=\"" + namePack + "\">");
            sb.append("\r\n"); //换行
            sb.append("\tinsert into ");
            sb.append(name + "(");
            sb.append("\r\n"); //换行

            //获取全部是属性名
            String[] strArr = getFiledName(obj);
            List<Map> list = new ArrayList<Map>(); //用于保存返回的jdbc类型
            StringBuffer st = new StringBuffer();
            if (strArr != null && strArr.length > 0){
                for (int i = 0; i < strArr.length; i ++ ){
                    String attributeName = strArr[i]; //获得属性名
                    String transformation = transformation(attributeName, obj);
                    if (!"jdbcType=暂无对应数据".equals(transformation)) {
                        Map map = new HashMap<>();
                        map.put("name", attributeName); //属性名
                        map.put("type", transformation); //字段类型
                        list.add(map);
                        if ((strArr.length - 1) == i) {
                            sb.append(attributeName); //最后一个就不需要逗号
                        } else {
                            if (i == 0){ //第一个的话加制表符，使格式化
                                sb.append("\t\t" + attributeName + ",");
                            } else {
                                sb.append(attributeName + ",");
                            }
                        }
                    } else {
                        //错误的进行记录，防止错误的漏了
                        st.append(attributeName);
                    }
                }
                sb.append("\r\n"); //换行
                sb.append("\t) values (");
                sb.append("\r\n"); //换行
                if (list != null && list.size() > 0){
                    for (int i = 0; i < list.size(); i ++){
                        if ((list.size() - 1) == i){
                            if ("error=1".equals(list.get(i).get("type"))){
                                sb.append("#{" + list.get(i).get("name") + "}");//最后一个就不需要逗号
                            } else {
                                sb.append("#{" + list.get(i).get("name") + "," + list.get(i).get("type") + "}");//最后一个就不需要逗号
                            }
                        } else {
                            if (i == 0){ //第一个的话加制表符，使格式化
                                //日期的暂时不指定
                                if ("error=1".equals(list.get(i).get("type"))){
                                    sb.append("\t\t" + "#{" + list.get(i).get("name") + "},");
                                } else {
                                    sb.append("\t\t" + "#{" + list.get(i).get("name") + "," + list.get(i).get("type") + "},");
                                }
                            } else {
                                //日期的暂时不指定
                                if ("error=1".equals(list.get(i).get("type"))){
                                    sb.append("#{" + list.get(i).get("name") + "},");
                                } else {
                                    sb.append("#{" + list.get(i).get("name") + "," + list.get(i).get("type") + "},");
                                }
                            }
                        }
                    }
                    sb.append("\r\n"); //换行
                    sb.append("\t)");
                }
            }

            sb.append("\r\n"); //换行
            sb.append("</insert>");
            System.out.println("\033[33;1m" + sb.toString() + "\033[0m");
            System.out.println("==========生成insert 语句 end==============================================================================");
            System.out.println("无法转换的属性：" + "\033[31;1m" + st + "\033[0m");

            Map m = new HashMap();
            m.put("id", sqlId); //xml上的id
            m.put("sql", sb.toString()); //生成的sql加拼好的外壳

            return m;
        }
        return null;
    }

    /**
     * 对文件夹位置进行初始化，没有就创建
     * path : 文件路径
     */
    public String init(String path){
        File file = new File(path);
        //判断目标文件所在的目录是否存在
        if (! folderisExists(file)){
            //如果目标文件所在的目录不存在，则创建目录（注意，如果是文件夹，应该是创建父目录，否则创建目录即可）
            boolean mkdirs = file.mkdirs();
            if (mkdirs){
                System.out.println("创建文件夹成功，path:" + path);
            }
        }

        return path;
    }

    /**
     * 创建文件并写入数据(注意，如果已经存在文件，是不会去进行重新生成或者插入的)
     * @param str 要写入的东西
     * @param file 要写入的文件
     */
    public void createFileWrite(String str, File file){
        //判断是否存在这个文件
        if (!fileIsExists(file)){
            try {
                //创建这个文件
                file.createNewFile();

                FileOutputStream writerStream = new FileOutputStream(file);
                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(writerStream, encode));
                //写入数据
                writer.write(str.toString());
                writer.close();
                System.out.println("路径：" + file.getPath());

            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("创建文件失败");
            }

        } else {
            System.out.println("已经存在mapper文件，不做处理");
        }
    }


    /**
     * 判断文件是否存在
     * @param file 文件
     * @return true 存在 false 不存在
     */
    public boolean fileIsExists(File file) {
        if (file.exists()) {
            //文件存在
            return true;
        } else {
            //文件不存在
            return false;
        }

    }

    /**
     * 文件夹是否存在
     * @param file
     * @return true 存在 false 不存在
     */
    public boolean folderisExists(File file){
        if (!file.exists() && !file.isDirectory()){
            //文件不存在
            return false;
        } else {
            //文件夹存在
            return true;
        }
    }

    /**
     * 根据属性名转换为对应的 mybatis 的 jdbcType类型
     * @param attribute 属性名
     * @param obj model
     * @return
     */
    public String transformation(String attribute, Object obj){
        String type = getHandleType(attribute, obj);
        if (type != null && !"".equals(type) && !"null".equals(type)){
            if ("String".equals(type)){
                return "jdbcType=VARCHAR";
            } else if ("BigDecimal".equals(type)){
                return "jdbcType=NUMERIC";
            } else if ("boolean".equals(type)){
                return "jdbcType=BOOLEAN";
            } else if ("byte".equals(type)){
                return "jdbcType=TINYINT";
            } else if ("short".equals(type)){
                return "jdbcType=SMALLINT";
            } else if ("int".equals(type)){
                return "jdbcType=INTEGER";
            } else if ("Integer".equals(type)){
                return "jdbcType=INTEGER";
            } else if ("long".equals(type)){
                return "jdbcType=BIGINT";
            } else if ("float".equals(type)){
                return "jdbcType=REAL";
            } else if ("double".equals(type)){
                return "jdbcType=DOUBLE";
            } else if ("Time".equals(type)){
                return "jdbcType=TIME";
            } else if ("Timestamp".equals(type)){
                return "jdbcType=TIMESTAMP";
            } else if ("Clob".equals(type)){
                return "jdbcType=CLOB";
            } else if ("Blob".equals(type)){
                return "jdbcType=BLOB";
            } else if ("Array".equals(type)){
                return "jdbcType=ARRAY";
            } else if ("Struct".equals(type)){
                return "jdbcType=STRUCT";
            } else if ("Long".equals(type)){
                return "jdbcType=BIGINT";
            /*注意，发现date类型存在一个问题。如果传入实体对象里的字段是java.util.Date或者java.sql.Date或者java.sql.Time或者java.sql.Timestamp
                1， jdbcType并未指定的情况下，则返回日期和时分秒，
                2, jdbcType指定为”JdbcType.DATE”，则只返回日期，不带时分秒
                3, jdbcType指定为”JdbcType.TIME”，则只有时分秒有效！
                上述情况，还与数据库有关系，现测试到sybase如果传入new Date(), 那么保存的只有日期，没有具体时间，所以日期暂时不指定jdbcType
                对于Ibatis操作Date/Time/DateTime，总结如下：
                    将pojo的属性类型设置为java.sql.Date（或java.sql.Time, java.sql.Timestamp），此时会严格遵循这三种类型的语义。但此方法因存在前文中提到的性能问题，在JDK1.6以前的JDK版本中能少使用就少使用。
                    如果你想在pojo中使用java.util.Date， 则要注意：
                    完整的日期时间，要确保jdbcType为空，或为DATE,TIME以外的值
                    只需要时间，要指定jdbcType=”TIME”
                    只需要日期，要指定jdbcType=”DATE”
                */
            }  else if ("Date".equals(type)){
//                return "jdbcType=DATE";
                return "error=1";
            } else if ("class [B".equals(type)){ //对应byte[]
                return "jdbcType=BINARY";
            } else {
                return "jdbcType=暂无对应数据";
            }
        }
        return "jdbcType=暂无对应数据";
    }

    /**
     * 获取字符串处理后的 属性类型
     *      经过本方法处理后的不在是 class java.lang.String  这种类型，而是 String 这样的类型
     * @param attribute 属性名
     * @param obj model
     * @return 属性对应的类型
     */
    private String getHandleType(String attribute, Object obj){
        List<Map> typeValueByName = getTypeValueByName(attribute, obj);
        if (typeValueByName != null && typeValueByName.size() == 1){
            String type = null;
            for (int i = 0; i < typeValueByName.size(); i ++ ){
                Map map = typeValueByName.get(0);
                type = (String)map.get("type");
            }
            if (type != null){
                int contain = type.indexOf(".");
                //判断是否有.来确定是否要截取
                if (contain != -1){
                    type = type.substring(type.lastIndexOf(".") + 1, type.length()); //截取 从 . 最后出现的位置开始
                    return type;
                } else {
                    return type;
                }
            }
        }

        return null;
    }

    /**
     * 根据属性名获取属性值 和 类型
     * @param fieldName 属性名
     * @param obj 对象
     * @return 属性值 和 类型
     */
    private List<Map> getTypeValueByName(String fieldName, Object obj){
        try {
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            String getTer = "get" + firstLetter + fieldName.substring(1);
            Method method = obj.getClass().getMethod(getTer, new Class[]{});
            Object value = method.invoke(obj, new Object[]{});
            List<Map> list = new ArrayList<>();
            Map map = new HashMap<>();
            map.put("value", value); //值
            Field declaredField = obj.getClass().getDeclaredField(fieldName);//根据属性名获取属性
            String type = declaredField.getType().toString();
            map.put("type", type);
            list.add(map);
            return list;
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | NoSuchFieldException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据属性名获取属性值
     * @param fieldName 属性名
     * @param obj 对象
     * @return 属性值
     */
    private Object getFieldValueByName(String fieldName, Object obj){
        try {
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            String getTer = "get" + firstLetter + fieldName.substring(1);
            Method method = obj.getClass().getMethod(getTer, new Class[]{});
            Object value = method.invoke(obj, new Object[]{});
            return value;
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取全部属性名并返回一个属性数组
     * */
    private String[] getFiledName(Object o){
        Field[] fields = o.getClass().getDeclaredFields(); // Field类的属性信息
        String[] fieldNames = new String[fields.length];
        for(int i = 0; i < fields.length; i ++){
            fieldNames[i]=fields[i].getName();
        }
        return fieldNames;
    }

    /**
     * 获取属性类型(type)，属性名(name)，属性值(value)的map组成的list
     * */
    private List getFiledsInfo(Object o){
        Field[] fields = o.getClass().getDeclaredFields();
        String[] fieldNames = new String[fields.length];
        List<Map> list = new ArrayList<Map>();
        Map infoMap = null;
        for(int i = 0; i < fields.length;i ++){
            infoMap = new HashMap();
            infoMap.put("type", fields[i].getType().toString());
            infoMap.put("name", fields[i].getName());
            infoMap.put("value", getFieldValueByName(fields[i].getName(), o));
            list.add(infoMap);
        }
        return list;
    }

    /**
     * 获取对象的所有属性值，返回一个对象数组
     * */
    public Object[] getFiledValues(Object o){
        String[] fieldNames=this.getFiledName(o);
        Object[] value=new Object[fieldNames.length];
        for(int i=0;i<fieldNames.length;i++){
            value[i]=this.getFieldValueByName(fieldNames[i], o);
        }
        return value;
    }


}
